/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * SaleInvoicePayment.java
 *
 * Created on Dec 20, 2010, 4:37:59 PM
 */
package ui;

import com.nanosl.lib.date.JXDatePicker;
import com.nanosl.lib.log.Loggings;
import ent.Bank;
import ent.CanceledInvoice;
import ent.CanceledInvoiceHasItem;
import ent.CollectionReceipt;
import ent.Customer;
import ent.Item;
import ent.SaleCash;
import ent.SaleCheque;
import ent.SaleChequePK;
import ent.SaleInvoice;
import ent.SaleInvoiceHasItem;
import ent.Stock;
import java.awt.Component;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
import util.Data;
import util.Printer;
import util.SuperView;

/**
 *
 * @author t
 */
public class SaleInvoicePaymentView extends SuperView {

    private static SaleInvoicePaymentView instance = new SaleInvoicePaymentView();

    public static void display() {
        getInstance().setVisible(true);
    }

    /**
     * @return the instance
     */
    public static SaleInvoicePaymentView getInstance() {
        return instance;
    }

    public SaleInvoicePaymentView() {
        onLoad();
    }

    /**
     * Creates new form SaleInvoicePayment
     */
    public SaleInvoicePaymentView(java.awt.Frame parent, boolean modal) {
        this();
        onLoad();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        invoiceTable = new javax.swing.JTable();
        jPanel2 = new javax.swing.JPanel();
        remainingAmountField = new javax.swing.JTextField();
        invoiceNumberField = new javax.swing.JTextField();
        customerNameField = new javax.swing.JTextField();
        amountField = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        invoiceDateField = new javax.swing.JTextField();
        cancelButton = new javax.swing.JButton();
        customerDetailsButton = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        paymentAmountTextField = new javax.swing.JTextField();
        chequeNumbertField = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        bankingDatePicker = new JXDatePicker();
        jLabel5 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        paymentTable = new javax.swing.JTable();
        bankComboBox = new javax.swing.JComboBox();
        jLabel9 = new javax.swing.JLabel();
        paidTextField = new javax.swing.JTextField();
        jLabel12 = new javax.swing.JLabel();
        processButton = new javax.swing.JButton();
        clearButton = new javax.swing.JButton();
        receiptNumberTextField = new javax.swing.JTextField();
        jLabel10 = new javax.swing.JLabel();
        receiptDatePicker = new JXDatePicker();
        jLabel11 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("SALE PAYMENT");

        invoiceTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Invoice"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        invoiceTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                invoiceTableMouseReleased(evt);
            }
        });
        invoiceTable.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                invoiceTableKeyReleased(evt);
            }
        });
        jScrollPane1.setViewportView(invoiceTable);
        invoiceTable.getColumnModel().getColumn(0).setResizable(false);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Selected Invoice"));

        remainingAmountField.setEditable(false);
        remainingAmountField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);

        invoiceNumberField.setEnabled(false);

        customerNameField.setEnabled(false);

        amountField.setEditable(false);
        amountField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);

        jLabel3.setText("Amount:");

        jLabel1.setText("Number:");

        jLabel4.setText("Remaining:");

        jLabel2.setText("Customer:");

        jLabel8.setText("Date:");

        invoiceDateField.setEnabled(false);

        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        customerDetailsButton.setText("Details");
        customerDetailsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                customerDetailsButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(invoiceNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(amountField, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel2Layout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jLabel8)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(invoiceDateField, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(jPanel2Layout.createSequentialGroup()
                                .addGap(26, 26, 26)
                                .addComponent(jLabel4)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(remainingAmountField, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(18, 18, 18)
                                .addComponent(cancelButton)))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(customerNameField)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(customerDetailsButton)))
                .addContainerGap())
        );

        jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {amountField, invoiceNumberField, remainingAmountField});

        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(invoiceNumberField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel8)
                    .addComponent(invoiceDateField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(customerNameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(customerDetailsButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(amountField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4)
                    .addComponent(remainingAmountField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cancelButton))
                .addContainerGap())
        );

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Payment"));

        paymentAmountTextField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
        paymentAmountTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                paymentAmountTextFieldActionPerformed(evt);
            }
        });

        chequeNumbertField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chequeNumbertFieldActionPerformed(evt);
            }
        });

        jLabel7.setText("Banking Date:");

        jLabel6.setText("Cheque Number:");

        bankingDatePicker.setName("bankingDatePicker"); // NOI18N
        bankingDatePicker.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                bankingDatePickerKeyPressed(evt);
            }
        });

        jLabel5.setText("Amount:");

        paymentTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Amount", "Cheque Number", "Banking Date", "Bank"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false, false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        paymentTable.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                paymentTableKeyReleased(evt);
            }
        });
        jScrollPane2.setViewportView(paymentTable);
        paymentTable.getColumnModel().getColumn(0).setCellRenderer(rightAlignCell);

        bankComboBox.setName("bankCombo"); // NOI18N
        bankComboBox.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                bankComboBoxKeyPressed(evt);
            }
        });

        jLabel9.setText("Bank:");

        paidTextField.setEditable(false);

        jLabel12.setText("Paid:");

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel6)
                            .addComponent(jLabel5))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(paymentAmountTextField)
                            .addComponent(chequeNumbertField, javax.swing.GroupLayout.DEFAULT_SIZE, 109, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel3Layout.createSequentialGroup()
                                .addComponent(jLabel7)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(bankingDatePicker, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                            .addGroup(jPanel3Layout.createSequentialGroup()
                                .addComponent(jLabel9)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(bankComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
                        .addComponent(jLabel12)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(paidTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(chequeNumbertField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7)
                    .addComponent(bankingDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(paymentAmountTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(bankComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel9))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(paidTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel12))
                .addContainerGap(14, Short.MAX_VALUE))
        );

        processButton.setText("Process");
        processButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                processButtonActionPerformed(evt);
            }
        });

        clearButton.setText("Clear");
        clearButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearButtonActionPerformed(evt);
            }
        });

        receiptNumberTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                receiptNumberTextFieldActionPerformed(evt);
            }
        });

        jLabel10.setText("Receipt:");

        receiptDatePicker.setName("receiptDatePicker"); // NOI18N
        receiptDatePicker.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                receiptDatePickerKeyPressed(evt);
            }
        });

        jLabel11.setText("Date:");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel11)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(receiptDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel10)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(receiptNumberTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(processButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(clearButton))
                    .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {clearButton, processButton});

        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(clearButton)
                            .addComponent(processButton)
                            .addComponent(receiptNumberTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel10)
                            .addComponent(receiptDatePicker, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel11))
                        .addContainerGap())
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jScrollPane1, 0, 0, Short.MAX_VALUE)
                        .addGap(40, 40, 40))))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void invoiceTableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_invoiceTableKeyReleased
        fill();
    }//GEN-LAST:event_invoiceTableKeyReleased

    private void invoiceTableMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_invoiceTableMouseReleased
        fill();
    }//GEN-LAST:event_invoiceTableMouseReleased

    private void paymentAmountTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_paymentAmountTextFieldActionPerformed
        addPay();
    }//GEN-LAST:event_paymentAmountTextFieldActionPerformed

    private void paymentTableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_paymentTableKeyReleased
        if (evt.getKeyCode() == 127) {
            deletePaymentRow(paymentTable.getSelectedRow());
        }
    }//GEN-LAST:event_paymentTableKeyReleased

    private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
        clearAll();
    }//GEN-LAST:event_clearButtonActionPerformed

    private void processButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_processButtonActionPerformed
        process();
    }//GEN-LAST:event_processButtonActionPerformed

    private void bankComboBoxKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_bankComboBoxKeyPressed
        if (evt.getKeyCode() == 10) {
            chequeNumbertField.requestFocus();
        }
    }//GEN-LAST:event_bankComboBoxKeyPressed

    private void chequeNumbertFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chequeNumbertFieldActionPerformed
        bankingDatePicker.requestFocus();
    }//GEN-LAST:event_chequeNumbertFieldActionPerformed

    private void bankingDatePickerKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_bankingDatePickerKeyPressed
        if (evt.getKeyCode() == 10) {
            amountField.requestFocus();
        }
    }//GEN-LAST:event_bankingDatePickerKeyPressed

    private void receiptDatePickerKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_receiptDatePickerKeyPressed
        if (evt.getKeyCode() == 10) {
            receiptNumberTextField.requestFocus();
        }
    }//GEN-LAST:event_receiptDatePickerKeyPressed

    private void receiptNumberTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_receiptNumberTextFieldActionPerformed
        processButton.requestFocus();
    }//GEN-LAST:event_receiptNumberTextFieldActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        cancelInvoice();
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void customerDetailsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_customerDetailsButtonActionPerformed
        CustomerView.display(customer);
    }//GEN-LAST:event_customerDetailsButtonActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                SaleInvoicePaymentView dialog = new SaleInvoicePaymentView(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                    @Override
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField amountField;
    private javax.swing.JComboBox bankComboBox;
    private org.jdesktop.swingx.JXDatePicker bankingDatePicker;
    private javax.swing.JButton cancelButton;
    private javax.swing.JTextField chequeNumbertField;
    private javax.swing.JButton clearButton;
    private javax.swing.JButton customerDetailsButton;
    private javax.swing.JTextField customerNameField;
    private javax.swing.JTextField invoiceDateField;
    private javax.swing.JTextField invoiceNumberField;
    private javax.swing.JTable invoiceTable;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTextField paidTextField;
    private javax.swing.JTextField paymentAmountTextField;
    private javax.swing.JTable paymentTable;
    private javax.swing.JButton processButton;
    private org.jdesktop.swingx.JXDatePicker receiptDatePicker;
    private javax.swing.JTextField receiptNumberTextField;
    private javax.swing.JTextField remainingAmountField;
    // End of variables declaration//GEN-END:variables
    DefaultTableModel invoiceDtm;
    DefaultTableModel paymentDtm;
    SaleInvoice saleInvoice;
    Customer customer;

    protected void onLoad() {
        initComponents();
        invoiceDtm = (DefaultTableModel) invoiceTable.getModel();
        paymentDtm = (DefaultTableModel) paymentTable.getModel();
        KeyAdapter();
    }

    @Override
    public void setVisible(boolean b) {
        super.setVisible(b);
        clearAll();
    }

    private void fillInvoiceTable() {
        invoiceDtm.setRowCount(0);
        paymentDtm.setRowCount(0);
        for (Iterator<SaleInvoice> it = m.find(SaleInvoice.class).iterator(); it.hasNext();) {
            SaleInvoice si = it.next();
            double receivedAmount = si.getReceivedAmount() == null ? 0 : si.getReceivedAmount();
            if (si.getAmount() > receivedAmount) {
                Object[] rowData = {si.getInvNo()};
                invoiceDtm.addRow(rowData);
            }
        }
    }

    private void fill() {
        saleInvoice = null;
        int selectedRow = invoiceTable.getSelectedRow();
        if (selectedRow > -1) {
            saleInvoice = m.find(SaleInvoice.class, invoiceTable.getValueAt(selectedRow, 0));
            fill(saleInvoice);
        }
    }

    public void fill(SaleInvoice saleInvoice) {
        clearAll();
        customer = saleInvoice.getCustomer();
        invoiceNumberField.setText(saleInvoice.getInvNo());
        invoiceDateField.setText(yyyy_MM_dd.format(saleInvoice.getInvTime()));
        customerNameField.setText(saleInvoice.getCustomer().getName());
        amountField.setText(nf2d.format(saleInvoice.getAmount()));
        double amount = saleInvoice.getAmount() == null ? 0 : saleInvoice.getAmount();
        double receivedAmount = saleInvoice.getReceivedAmount() == null ? 0 : saleInvoice.getReceivedAmount();
        remainingAmountField.setText(nf2d.format(amount - receivedAmount));
    }

    private void addPay() {
        try {
            double paymentAmount = Double.valueOf(paymentAmountTextField.getText().trim());
            if (paymentAmount > 0) {
                String chequeNumber = chequeNumbertField.getText().trim();
                if (!chequeNumber.equals("")) {
                    Date bankingDate = bankingDatePicker.getDate();
                    if (bankingDate != null) {
                        Object[] row = {nf2d.format(paymentAmount), chequeNumber, yyyy_MM_dd.format(bankingDate), ((Bank) bankComboBox.getSelectedItem()).getCode()};
                        fillPaymentTable(row);
                    }
                } else {
                    for (int i = 0; i < paymentTable.getRowCount(); i++) {
                        if (paymentTable.getValueAt(i, 1) == null) {
                            paymentAmount += Double.valueOf(paymentTable.getValueAt(i, 0).toString());
                            paymentTable.setValueAt(nf2d.format(paymentAmount), i, 0);
                            clearPaymentFields();
                            calcRemaining();
                            return;
                        }
                    }
                    Object[] row = {nf2d.format(paymentAmount)};
                    fillPaymentTable(row);
                }
            }
        } catch (NumberFormatException e) {
        } catch (Exception e) {
            Loggings.logError(getName(), e);
        }
    }

    private void fillPaymentTable(Object[] row) {
        paymentDtm.addRow(row);
        clearPaymentFields();
        calcRemaining();
        calcPaid();
    }

    private void deletePaymentRow(int selectedRow) {
        if (selectedRow > -1) {
            paymentDtm.removeRow(selectedRow);
            calcRemaining();
        }
    }

    private void calcRemaining() {
        SaleInvoice saleInvoice = m.find(SaleInvoice.class, invoiceNumberField.getText().trim());
        double remaining = saleInvoice.getAmount() - (saleInvoice.getReceivedAmount() == null ? 0 : saleInvoice.getReceivedAmount());
        int rowCount = paymentTable.getRowCount();
        for (int i = 0; i < rowCount; i++) {
            remaining = remaining - Double.valueOf(paymentTable.getValueAt(i, 0).toString());
        }
        remainingAmountField.setText(nf2d.format(remaining));
    }

    private void clearPaymentFields() {
        chequeNumbertField.setText("");
        paymentAmountTextField.setText("");
    }

    private void clearAll() {
        invoiceNumberField.setText("");
        invoiceDateField.setText("");
        customerNameField.setText("");
        amountField.setText("");
        remainingAmountField.setText("");
        paidTextField.setText("");
        clearPaymentFields();
        paymentDtm.setRowCount(0);
        customer = null;
        fillInvoiceTable();
        fillBanks();
    }

    private void process() {
        int rowCount = paymentTable.getRowCount();
        if (rowCount == 0) {
            return;
        }
        try {
            List<Serializable> serializables = new ArrayList<Serializable>();
            String invoiceNumber = invoiceNumberField.getText().trim();
            SaleInvoice saleInvoice = m.find(SaleInvoice.class, invoiceNumber);
            String receiptNumber = receiptNumberTextField.getText().trim();
            double paidAmount = Double.parseDouble(paidTextField.getText().trim());
            if (receiptNumber.isEmpty()) {
                showError("Receipt Number Required.");
                return;
            }
            CollectionReceipt collectionReceipt = m.find(CollectionReceipt.class, receiptNumber);
            if (collectionReceipt != null) {
                showError("Receipt " + receiptNumber + " Already Updated.");
                return;
            }
            collectionReceipt = new CollectionReceipt(receiptNumber);
            Date collectedTime = receiptDatePicker.getDate();
            double collectedAmount = Double.valueOf(paidTextField.getText().trim());
            collectionReceipt.setCollectedTime(collectedTime);
            collectionReceipt.setSaleInvoice(saleInvoice);
            collectionReceipt.setCash(collectedAmount);

            List<SaleCheque> saleCheques = new ArrayList<SaleCheque>();
            for (int i = 0; i < rowCount; i++) {
                Object o = paymentTable.getValueAt(i, 1);
                String chequeNumber = o == null ? "" : o.toString().trim();
                double amount = Double.valueOf(paymentTable.getValueAt(i, 0).toString());
                if (chequeNumber.equals("")) {
                    SaleCash saleCash = new SaleCash(receiptNumber);
                    saleCash.setAmount(amount);
                    saleCash.setCollectionReceipt(collectionReceipt);
                    collectionReceipt.setSaleCash(saleCash);
                    serializables.add(saleCash);
                } else {
                    Date bankingDate = yyyy_MM_dd.parse(paymentTable.getValueAt(i, 2).toString());
                    String bankCode = paymentTable.getValueAt(i, 3).toString();
                    Bank bank = m.find(Bank.class, bankCode);
                    SaleChequePK saleChequePK = new SaleChequePK(chequeNumber, bankCode, receiptNumber);
                    SaleCheque saleCheque = new SaleCheque(saleChequePK);
                    saleCheque.setAmount(amount);
                    saleCheque.setBank(bank);
                    saleCheque.setBankingDate(bankingDate);
                    saleCheque.setCollectionReceipt(collectionReceipt);
                    saleCheque.setStatus(0);
                    saleCheques.add(saleCheque);
                    serializables.add(saleCheque);
                }
            }
            collectionReceipt.setSaleChequeCollection(saleCheques);
            serializables.add(collectionReceipt);
            double remainingAmount = Double.valueOf(remainingAmountField.getText().trim());
            saleInvoice.setCredit(remainingAmount);
            saleInvoice.setReceivedAmount(saleInvoice.getAmount() - remainingAmount);
            serializables.add(saleInvoice);
            if (m.update(serializables)) {
                Map<String, Object> params = new LinkedHashMap<String, Object>();
                params.put("invoice", invoiceNumber);
                params.put("receipt", receiptNumber);
                params.put("paidAmount", paidAmount);
                Printer.printReceipt(params);
                setStatusMessage("Update Success.");
                clearAll();
                return;
            }
        } catch (Exception ex) {
            Loggings.logError(getName(), ex);
        }
        showError("Unable to complete payment!");
    }

    private void fillBanks() {
        bankComboBox.setModel(new DefaultComboBoxModel(m.find(Bank.class).toArray()));
    }

    private void KeyAdapter() {
        AutoCompleteDecorator.decorate(bankComboBox);
        setComboBoxKeyAdapters(bankComboBox);
        setComboBoxKeyAdapters(bankingDatePicker);
        setComboBoxKeyAdapters(receiptDatePicker);
    }

    private void setComboBoxKeyAdapters(JComponent comp) {
        String compName = comp.getName();
        Component component[] = comp.getComponents();
        for (int i = 0; i < component.length; i++) {
            if (compName.equals("bankCombo")) {
                component[i].addKeyListener(bankComboBoxKeyAdapter);
            } else if (compName.equals("bankingDatePicker")) {
                component[i].addKeyListener(bankingDatePickerKeyAdapter);
            } else if (compName.equals("receiptDatePicker")) {
                component[i].addKeyListener(receiptDatePickerKeyAdapter);
            }

        }
    }
    KeyAdapter bankComboBoxKeyAdapter = new java.awt.event.KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent evt) {
            bankComboBoxKeyAdapter.keyPressed(evt);
        }
    };
    KeyAdapter bankingDatePickerKeyAdapter = new java.awt.event.KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent evt) {
            bankingDatePickerKeyPressed(evt);
        }
    };
    KeyAdapter receiptDatePickerKeyAdapter = new java.awt.event.KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent evt) {
            receiptDatePickerKeyPressed(evt);
        }
    };

    private void cancelInvoice() {
        String invoiceNumber = invoiceNumberField.getText().trim();
        SaleInvoice saleInvoice = m.find(SaleInvoice.class, invoiceNumber);
        if (saleInvoice == null) {
            showError("No Invoice Selected.");
            return;
        }
        if (saleInvoice.getReceivedAmount() > 0) {
            showError("Allowed only non paid Invoices.");
            return;
        }
        int c = JOptionPane.showConfirmDialog(this, "Are you sure to cancel the Invoice and Return the items to stock?", "Confirm", JOptionPane.YES_NO_OPTION);
        if (c != JOptionPane.YES_OPTION) {
            return;
        }
        CanceledInvoice canceledInvoice = new CanceledInvoice(invoiceNumber);
        Collection<CanceledInvoiceHasItem> canceledInvoiceHasItems = new ArrayList<CanceledInvoiceHasItem>();

        Collection<SaleInvoiceHasItem> saleInvoiceHasItems = saleInvoice.getSaleInvoiceHasItemCollection();
        List<Serializable> serializables = new ArrayList<Serializable>();
        for (Iterator<SaleInvoiceHasItem> it = saleInvoiceHasItems.iterator(); it.hasNext();) {
            SaleInvoiceHasItem saleInvoiceHasItem = it.next();
            Item item = m.find(Item.class, saleInvoiceHasItem.getItem().getCode());
            CanceledInvoiceHasItem canceledInvoiceHasItem = new CanceledInvoiceHasItem(invoiceNumber, item.getCode());
            canceledInvoiceHasItem.setCanceledInvoice(canceledInvoice);
            canceledInvoiceHasItem.setItem(item);
            canceledInvoiceHasItem.setDiscount(saleInvoiceHasItem.getDiscount());
            canceledInvoiceHasItem.setQuantity(saleInvoiceHasItem.getQuantity());
            canceledInvoiceHasItem.setRate(saleInvoiceHasItem.getRate());
            canceledInvoiceHasItems.add(canceledInvoiceHasItem);
            serializables.add(canceledInvoiceHasItem);
            Stock stock = item.getStock();
            double remainingQuantity = stock.getQuantity();
            stock.setQuantity(remainingQuantity + saleInvoiceHasItem.getQuantity());
            serializables.add(stock);
        }
        canceledInvoice.setAmount(saleInvoice.getAmount());
        canceledInvoice.setCredit(saleInvoice.getCredit());
        canceledInvoice.setCustomer(saleInvoice.getCustomer());
        canceledInvoice.setDiscount(saleInvoice.getDiscount());
        canceledInvoice.setInvTime(saleInvoice.getInvTime());
        canceledInvoice.setOperator(Data.getOperator().getEmployee().getCode());
        canceledInvoice.setReceivedAmount(saleInvoice.getReceivedAmount());
        canceledInvoice.setCanceledInvoiceHasItemCollection(canceledInvoiceHasItems);
        serializables.add(canceledInvoice);
        if (m.update(serializables)) {
            m.delete(SaleInvoice.class, saleInvoice.getInvNo());
            setStatusMessage("Invoice Canceled");
            clearAll();
        }
    }

    private void calcPaid() {
        double paid = 0;
        for (int i = 0; i < paymentDtm.getRowCount(); i++) {
            paid += Double.valueOf(paymentDtm.getValueAt(i, 0).toString());
        }
        paidTextField.setText(nf2d.format(paid));
    }
}
